home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / fpoly256.zip / FTRIBLTX.ASM < prev    next >
Assembly Source File  |  1992-01-27  |  9KB  |  426 lines

  1.     TITLE    FASTRI - Fast triangle poly filling blitter
  2.     NAME    FTRIBLTX
  3.  
  4.  
  5.     COMMENT    $
  6.  
  7.     Name:        FTRIBLTX
  8.  
  9.         Written and (c) by Dave Stampe 9/11/91
  10.         Not for commercial use, so get permission
  11.         before marketing code using this stuff!
  12.         For private PD use only.
  13.  
  14.         $
  15.  
  16.         .MODEL large
  17.  
  18.         .CODE
  19.                 ; big table more eff. than masking
  20.                 ; start byte lookup table
  21. stmask:        REPT    80
  22.         db    15,14,12,8
  23.         ENDM
  24.                 ; end byte lookup table
  25. fnmask:         REPT    80
  26.         db      1,3,7,15
  27.         ENDM
  28.  
  29.     extrn    _dpaddr        ; page base address
  30.  
  31. x1    equ    [bp+6]          ; arguments to _tpoly
  32. y1    equ    [bp+8]
  33. x2    equ    [bp+10]
  34. y2    equ    [bp+12]
  35. x3    equ    [bp+14]
  36. y3     equ    [bp+16]
  37.  
  38.  
  39. vline   equ    [bp-2]       ; video base addr. of line
  40. lines    equ    [bp-4]        ; number of lines to fill
  41. l_incr    equ    [bp-8]
  42. r_incr    equ    [bp-12]
  43. aswap   equ     [bp-16]        ; plane mask reg. swap value
  44.  
  45.    ;
  46.    ;   fastri(int x1,int y1, int x2, int y2, int x3, int y3)
  47.    ;       vertices must be in CCW order!
  48.  
  49.         PUBLIC    _fastri
  50.  
  51. _fastri    proc    far
  52.  
  53.     .386
  54.     push    bp
  55.     mov    bp,sp
  56.     sub    sp,16
  57.     push    si
  58.     push    di
  59.  
  60.     mov    eax,x1    ; consider as 32-bit hash: look for top, then left
  61.     mov    ebx,x2
  62.     mov    ecx,x3
  63.     cmp    ebx,eax
  64.     jae    nrot1
  65.     xchg    eax,ebx    ; rotate till top-left is at head of list
  66.     xchg    ebx,ecx
  67.     cmp    ebx,eax
  68.     jae    donerot
  69.     xchg    eax,ebx
  70.     xchg    ebx,ecx
  71.     jmp    donerot
  72.  
  73. nrot1:    cmp    ecx,eax
  74.     jae    donerot
  75.     xchg    eax,ecx
  76.     xchg    ebx,ecx
  77.  
  78. donerot:
  79.     mov    x1,eax
  80.     mov    x2,ebx
  81.     mov    x3,ecx
  82.  
  83.     cld
  84.     mov    ax,03c5h        ; setup DX adr. swap value
  85.     mov    aswap,ax
  86.     mov    ax,0a000h               ; set video segment
  87.     mov    es,ax
  88.     mov    al,y1
  89.     mov    bl,80                   ; compute starting line adr
  90.     mul    bl
  91.     add    ax,WORD PTR ds:_dpaddr
  92.     mov    vline,ax
  93.  
  94.     mov    ax,y1     ; determine config. of vertices: one of:
  95.     cmp    ax,y3
  96.     jz    flattop
  97.     mov    ax,y2     ; 1  3      1      1      1
  98.     cmp    ax,y3     ;                2          3
  99.     jz    flatbot   ;  2      2  3     3     2
  100.     jb    onleft
  101.     jmp    onright
  102.  
  103. flatbot:
  104.     movzx    ecx,word ptr y2       ; check for sliver poly
  105.     sub    cx,y1
  106.     jz    finished
  107.     mov    lines,cx
  108.     mov    ax,x2
  109.     sub    ax,x1
  110.     movsx    eax,ax      ; conv. to double prec. << 16
  111.     je    roundpl1    ; zero slope
  112.     cmp    cx,1
  113.     je    roundpl1
  114.     cdq
  115.     shl    eax,16        ; (x2-x1)/(y2-y1)
  116.     idiv    ecx
  117.     cmp        eax,0       ; round up if pos (neg already rounded up)
  118.     jle    roundpl1
  119.     inc    eax
  120. roundpl1:
  121.     mov    l_incr,eax
  122.  
  123.     mov    ax,x3
  124.     sub    ax,x1
  125.     movsx    eax,ax      ; conv. to double prec. << 16
  126.     je    roundpl2    ; zero slope
  127.     cmp    cx,1
  128.     je    roundpl2
  129.     cdq
  130.     shl    eax,16        ; (x2-x1)/(y2-y1)
  131.     idiv    ecx
  132.     cmp        eax,0       ; round up if pos (neg already rounded up)
  133.     jle    roundpl2
  134.     inc    eax
  135. roundpl2:
  136.     mov    r_incr,eax
  137.     cmp    eax,l_incr
  138.     jz    finished        ; sliver: don't bother
  139.  
  140.     mov    dx,x1            ; compute L,R start
  141.     mov    cx,dx
  142.     shl    edx,16
  143.     mov    bx,cx
  144.     mov    esi,edx
  145.     add    edx,08000h             ; force left side to round up
  146.  
  147.     call    near ptr trapezoid
  148.     jmp    finished
  149.  
  150. flattop:
  151.     movzx    ecx,word ptr y2       ; check for sliver poly
  152.     sub    cx,y1
  153.     jz    finished
  154.     mov    lines,cx
  155.     mov    ax,x2
  156.     sub    ax,x1
  157.     movsx    eax,ax      ; conv. to double prec. << 16
  158.     je    roundpl3    ; zero slope
  159.     cmp    cx,1
  160.     je    roundpl3    ; no slope needed if 1 line only
  161.     cdq
  162.     shl    eax,16        ; (x2-x1)/(y2-y1)
  163.     idiv    ecx
  164.     cmp        eax,0       ; round up if pos (neg already rounded up)
  165.     jle    roundpl3
  166.     inc    eax
  167. roundpl3:
  168.     mov    l_incr,eax
  169.  
  170.     mov    ax,x2
  171.     sub    ax,x3
  172.     movsx    eax,ax      ; conv. to double prec. << 16
  173.     je    roundpl4    ; zero slope
  174.     cmp    cx,1
  175.     je    roundpl4    ; no slope needed if 1 line only
  176.     cdq
  177.     shl    eax,16        ; (x2-x1)/(y2-y1)
  178.     idiv    ecx
  179.     cmp        eax,0       ; round up if pos (neg already rounded up)
  180.     jle    roundpl4
  181.     inc    eax
  182. roundpl4:
  183.     mov    r_incr,eax
  184.     cmp    eax,l_incr
  185.     jz    finished        ; sliver: don't bother
  186.  
  187.     movzx    edx,word ptr x1             ; compute L,R start
  188.     mov    bx,dx
  189.     shl    edx,16
  190.     add    edx,08000h             ; force left side to round up
  191.     movzx    esi,word ptr x3
  192.     mov    cx,si
  193.     shl    esi,16
  194.  
  195.     call    near ptr trapezoid
  196.     jmp    finished
  197.  
  198. onleft:
  199.     movzx    ecx,word ptr y2       ; compute first slice height
  200.     sub    cx,y1
  201.     je    finished    ; sliver poly
  202.     mov    lines,cx
  203.     mov    ax,x2
  204.     sub    ax,x1
  205.     movsx    eax,ax      ; conv. to double prec. << 16
  206.     je    roundpl5    ; zero slope
  207.     cmp    cx,1
  208.     je    roundpl5
  209.     cdq
  210.     shl    eax,16        ; (x2-x1)/(y2-y1)
  211.     idiv    ecx
  212.     cmp        eax,0       ; round up if pos (neg already rounded up)
  213.     jle    roundpl5
  214.     inc    eax
  215. roundpl5:
  216.     mov    l_incr,eax
  217.  
  218.     movzx    ecx,word ptr y3
  219.     sub    cx,y1
  220.     mov    ax,x3
  221.     sub    ax,x1
  222.     movsx    eax,ax      ; conv. to double prec. << 16
  223.     je    roundpl6    ; zero slope
  224.     cmp    cx,1
  225.     je    roundpl6
  226.     cdq
  227.     shl    eax,16        ; (x2-x1)/(y2-y1)
  228.     idiv    ecx
  229.     cmp        eax,0       ; round up if pos (neg already rounded up)
  230.     jle    roundpl6
  231.     inc    eax
  232. roundpl6:
  233.     mov    r_incr,eax
  234.     cmp    eax,l_incr
  235.     jz    finished        ; sliver: don't bother
  236.  
  237.     mov    dx,x1            ; compute L,R start
  238.     mov    cx,dx
  239.     shl    edx,16
  240.     mov    bx,cx
  241.     mov    esi,edx
  242.     add    edx,08000h             ; force left side to round up
  243.  
  244.     call    near ptr trapezoid
  245.     push    esi        ; save full precison right side
  246.  
  247.     movzx    ecx,word ptr y3       ; compute second slice height
  248.     sub    cx,y2
  249.     mov    lines,cx
  250.     mov    ax,x3
  251.     sub    ax,x2
  252.     movsx    eax,ax      ; conv. to double prec. << 16
  253.     je    roundpl7    ; zero slope
  254.     cmp    cx,1
  255.     je    roundpl7
  256.     cdq
  257.     shl    eax,16        ; (x2-x1)/(y2-y1)
  258.     idiv    ecx
  259.     cmp        eax,0       ; round up if pos (neg already rounded up)
  260.     jle    roundpl7
  261.     inc    eax
  262. roundpl7:
  263.     mov    l_incr,eax   ; change left increment
  264.  
  265.     pop    esi
  266.     mov    ecx,esi         ; restore right side
  267.     shr    ecx,16
  268.  
  269.     movzx    edx,word ptr x2             ; compute L start
  270.     mov    bx,dx
  271.     shl    edx,16
  272.     add    edx,08000h        ; force left side to round up
  273.  
  274.     call    near ptr trapezoid
  275.     jmp    finished
  276.  
  277. onright:
  278.     movzx    ecx,word ptr y2       ; compute first slice height
  279.     sub    cx,y1
  280.     je    finished
  281.     mov    ax,x2
  282.     sub    ax,x1
  283.     movsx    eax,ax      ; conv. to double prec. << 16
  284.     je    roundpl8    ; zero slope
  285.     cmp    cx,1
  286.     je    roundpl8
  287.     cdq
  288.     shl    eax,16        ; (x2-x1)/(y2-y1)
  289.     idiv    ecx
  290.     cmp        eax,0       ; round up if pos (neg already rounded up)
  291.     jle    roundpl8
  292.     inc    eax
  293. roundpl8:
  294.     mov    l_incr,eax
  295.  
  296.     movzx    ecx,word ptr y3       ; compute first slice height
  297.     sub    cx,y1
  298.     mov    lines,cx
  299.     mov    ax,x3
  300.     sub    ax,x1
  301.     movsx    eax,ax      ; conv. to double prec. << 16
  302.     je    roundpl9    ; zero slope
  303.     cmp    cx,1
  304.     je    roundpl9
  305.     cdq
  306.     shl    eax,16        ; (x2-x1)/(y2-y1)
  307.     idiv    ecx
  308.     cmp        eax,0       ; round up if pos (neg already rounded up)
  309.     jle    roundpl9
  310.     inc    eax
  311. roundpl9:
  312.     mov    r_incr,eax
  313.     cmp    eax,l_incr
  314.     jz    finished        ; sliver: don't bother
  315.  
  316.     mov    dx,x1           ; compute L,R start
  317.     mov    cx,dx
  318.     shl    edx,16
  319.     mov    bx,cx
  320.     mov    esi,edx
  321.     add    edx,08000h             ; force left side to round up
  322.  
  323.     call    near ptr trapezoid
  324.     push    edx        ; save full precison left side
  325.  
  326.     movzx    ecx,word ptr y2       ; compute second slice height
  327.     sub    cx,y3
  328.     mov    lines,cx
  329.     mov    ax,x2
  330.     sub    ax,x3
  331.     movsx    eax,ax      ; conv. to double prec. << 16
  332.     je    roundpla    ; zero slope
  333.     cmp    cx,1
  334.     je    roundpla
  335.     cdq
  336.     shl    eax,16        ; (x2-x1)/(y2-y1)
  337.     idiv    ecx
  338.     cmp        eax,0       ; round up if pos (neg already rounded up)
  339.     jle    roundpla
  340.     inc    eax
  341. roundpla:
  342.     mov    r_incr,eax   ; change left increment
  343.  
  344.     pop    edx
  345.     mov    ebx,edx         ; restore left side
  346.     shr    ebx,16
  347.  
  348.     movzx    esi,word ptr x3             ; compute R start
  349.     mov    cx,si
  350.     shl    esi,16
  351.  
  352.     call    near ptr trapezoid
  353.     jmp    finished
  354.  
  355.  
  356. finished:
  357.     pop    di                         ; exit code
  358.     pop    si
  359.     mov    sp,bp
  360.     pop    bp
  361.     ret
  362.  
  363. _fastri    endp
  364.  
  365.  
  366.  
  367. trapezoid:    ; call with  bx = left, cx = right
  368.         ; edx = (left+0.5)>>16, esi = right<<16
  369.         ; vline, lines, l_incr, r_incr all set up
  370.  
  371. nextline:
  372.         ; start of fast h line blitter:
  373.         ;  bx=left side, cx=right side, vline=line start
  374.  
  375.     xchg    dx,aswap
  376.  
  377.     mov    al,BYTE PTR cs:[bx+stmask]  ; left mask
  378.     shr    bx,2                        ; left address
  379.  
  380.     mov    di,cx
  381.     mov    ah,BYTE PTR cs:[di+fnmask]  ; right mask
  382.     shr    cx,2                        ; right address
  383.  
  384.     mov    di,vline            ; start address
  385.     add    di,bx
  386.     sub    cx,bx                       ; number of bytes-1
  387.     je    short onebyte
  388.     jc    short doneline              ; clip trap
  389.  
  390.     out    dx,al
  391.     stosb                            ; mask first byte
  392.     dec    cx                          ; mask rest
  393.     mov    al,0ffh                     ; rep faster than test and jmp
  394.     out    dx,al
  395.     rep    stosb
  396.  
  397.     mov    al,ah
  398.     out    dx,al
  399.     mov    es:[di],ah                  ; mask last byte
  400.     jmp    short doneline
  401.  
  402. onebyte:
  403.     and    al,ah
  404.     out    dx,al
  405.     mov    es:[di],al        ; single byte mask
  406.  
  407. doneline:
  408.     xchg    dx,aswap
  409.     mov    ax,80                   ; next line address
  410.     add    vline,ax
  411.  
  412.     add    edx,DWORD PTR l_incr    ; step left, right edges
  413.     add    esi,DWORD PTR r_incr
  414.     mov    ebx,edx            ; convert fixed pt to integer
  415.     sar    ebx,16
  416.     mov    ecx,esi
  417.     sar    ecx,16
  418.  
  419.     dec    WORD PTR lines          ; done lines?
  420.     jg    short nextline
  421.  
  422. donetri:                                ; finished all drawing
  423. exit:
  424.     retn
  425.  
  426.     end